home *** CD-ROM | disk | FTP | other *** search
- /*
- * Txtr_Geometry.c
- *
- * This is a simple library illustrating trigrid and box geometries. The trigrids
- * represented are Square, Torus, Wavey Torus, Splash, Sphere, Cone, Pipe, Steps,
- * and Spring.
- *
- * NewLibraryTriGrid returns a trigrid geometry when kGeometryLibraryRange_Simple
- * is added to the trigrid number (0 to 8) or a trigrid with shading uv attributes
- * when kGeometryLibraryRange_UVGeoAttributes or kGeometryLibraryRange_UVFaceAttributes
- * is added to the trigrid number.
- *
- * Note: The calculation of uv's may be flipping the texture.
- *
- *
- * Robert Dierkes
- * © 1995 Apple Computer, Inc.
- *
- * 03/22/95 RDD Created.
- * 09/20/95 RDD Cleanup.
- * 11/13/95 RDD Changed macro to DebugStr.
- */
-
- /*------------------*/
- /* Include Files */
- /*------------------*/
- #include <Memory.h>
- #include <math.h>
-
- #include "QD3D.h"
- #include "QD3DGeometry.h"
- #include "QD3DMath.h"
- #include "QD3DSet.h"
-
- #include "Txtr_Geometry.h"
- #include "Txtr_Math.h"
- #include "Txtr_Error.h"
-
-
- /*----------------------*/
- /* Local Prototypes */
- /*----------------------*/
- static
- void AddVertexNormals(
- unsigned long geoNum,
- TQ3TriGridData *pTriData);
-
-
-
- unsigned long GetLibraryMaxSimpleBox(void)
- {
- return kGeometryLibrary_BoxMaxSimple;
- }
-
-
- unsigned long GetLibraryMaxSimpleTriGrid(void)
- {
- return kGeometryLibrary_TriGridMaxSimple;
- }
-
-
-
- TQ3GeometryObject NewLibraryBox(
- unsigned long num)
- {
- TQ3GeometryObject geometryObject = NULL;
- TQ3BoxData boxData;
-
- switch (num)
- {
- case kGeometryLibraryRange_Simple+0: /* Box */
- Q3Point3D_Set(&boxData.origin, -0.5,-0.5,-0.5);
- Q3Vector3D_Set(&boxData.orientation, 0.0, 1.0, 0.0);
- Q3Vector3D_Set(&boxData.majorAxis, 0.0, 0.0, 1.0);
- Q3Vector3D_Set(&boxData.minorAxis, 1.0, 0.0, 0.0);
- boxData.boxAttributeSet = NULL;
- boxData.faceAttributeSet = NULL;
-
- geometryObject = Q3Box_New(&boxData);
- break;
-
- case kGeometryLibraryRange_Simple+1: /* Skewed Box */
- Q3Point3D_Set(&boxData.origin, -0.75,-0.5,-0.75);
- Q3Vector3D_Set(&boxData.orientation, 0.5, 1.0, 0.5);
- Q3Vector3D_Set(&boxData.majorAxis, 0.0, 0.0, 1.0);
- Q3Vector3D_Set(&boxData.minorAxis, 1.0, 0.0, 0.0);
- boxData.boxAttributeSet = NULL;
- boxData.faceAttributeSet = NULL;
-
- geometryObject = Q3Box_New(&boxData);
- break;
-
- default:
- DebugStr("\pWarning: NewLibraryBox ; unknown box index");
- return NULL;
- break;
- }
-
- return geometryObject;
- }
-
-
- /*
- * NewLibraryTriGrid
- *
- * There are two methods below for creating trigrid vertices. If the trigrid is:
- *
- * 1. planar (relatively) then the vvValue (an x-coordinate) increases from vvMin to vvMax.
- * 2. a cross section revolved about the Y axis then the vvValue (an angle) decreases from
- * vvMax to vvMin in a counter-clockwise manner about the axis. This puts the correct
- * side of the trigrid facing outward for texture uvs.
- *
- * In both cases, uuValue decreases from uuMax to uuMin from postive to negative Y.
- *
- * TriGrid vertex index numbering
- *
- * (i)
- * 8 9 10 11
- * 4 5 6 7
- * 0 1 2 3
- *
- *
- * UVs for an upright texture continuous across the trigrid
- *
- * (U,V)
- * (x,y)
- *
- * ^ + 0.0, 1.0 0.33, 1.0 0.66, 1.0 1.0, 1.0
- * | 0.0, 0.5 0.33, 0.5 0.66, 0.5 1.0, 0.5
- * V - 0.0, 0.0 0.33, 0.0 0.66, 0.0 1.0, 0.0
- *
- * U -->
- * - +
- *
- * UVs for an upright repeated texture
- *
- * (U,V)
- * (x,y)
- *
- * ^ + 0,2 1,2 2,2 3,2
- * | 0,1 1,1 2,1 3,1
- * V - 0,0 1,0 2,0 3,0
- *
- * U -->
- * - +
- */
- TQ3GeometryObject NewLibraryTriGrid(
- unsigned long num)
- {
- TQ3GeometryObject geometryObject = NULL;
- TQ3TriGridData data;
- TQ3Vertex3D *vertices;
- unsigned long i;
- float uuValue, vvValue,
- uuMin, uuMax, uuStep,
- vvMin, vvMax, vvStep,
- radius;
- TQ3Boolean hasUVAttributes;
- TQ3Param2D param2D;
- TQ3Boolean addNormals;
-
- hasUVAttributes = (TQ3Boolean) (mHasUVGeoAttributes(num) || mHasUVFaceAttributes(num));
-
- switch (num)
- {
- case kGeometryLibraryRange_Simple+0: /* Flat 5x5 */
- case kGeometryLibraryRange_UVGeoAttributes+0:
- case kGeometryLibraryRange_UVFaceAttributes+0:
- case kGeometryLibraryRange_Simple+3: /* Splash */
- case kGeometryLibraryRange_UVGeoAttributes+3:
- case kGeometryLibraryRange_UVFaceAttributes+3:
- case kGeometryLibraryRange_Simple+7: /* Steps */
- case kGeometryLibraryRange_UVGeoAttributes+7:
- case kGeometryLibraryRange_UVFaceAttributes+7:
- {
- addNormals = kQ3False;
-
- /* Setup min, max and step values trigrid vertex u & v values */
- switch (num)
- {
- /**
- ** Flat 5x5
- **/
- case kGeometryLibraryRange_Simple+0:
- case kGeometryLibraryRange_UVGeoAttributes+0:
- case kGeometryLibraryRange_UVFaceAttributes+0:
-
- /*
- * uuValue is an x-coordinate
- * vvValue is a y-coordinate
- */
- uuMin = -0.5;
- uuMax = 0.5;
- uuStep = 0.25;
-
- vvMin = -0.5;
- vvMax = 0.5;
- vvStep = 0.25;
- break;
-
- /**
- ** Splash
- **/
- case kGeometryLibraryRange_Simple+3:
- case kGeometryLibraryRange_UVGeoAttributes+3:
- case kGeometryLibraryRange_UVFaceAttributes+3:
-
- addNormals = kQ3True;
-
- /*
- * uuValue is an x-coordinate
- * vvValue is a y-coordinate
- */
- uuMin = -3.5;
- uuMax = 3.5;
- vvMin = -3.5;
- vvMax = 3.5;
- if (hasUVAttributes) {
- uuStep = 0.35;
- vvStep = 0.35;
- } else {
- uuStep = 0.25;
- vvStep = 0.25;
- }
- break;
-
- /**
- ** Steps
- **/
- case kGeometryLibraryRange_Simple+7:
- case kGeometryLibraryRange_UVGeoAttributes+7:
- case kGeometryLibraryRange_UVFaceAttributes+7:
-
- /*
- * uuValue is an x-coordinate
- * vvValue is a y-coordinate
- */
- #define kStepScale 0.2
-
- uuMin = -4.5;
- uuMax = 4.5;
- uuStep = 0.5;
-
- vvMin = -4.5;
- vvMax = 4.5;
- vvStep = 0.5;
- break;
-
- default:
- DebugStr("\pWarning: NewLibraryTriGrid ; unknown flat trigrid index");
- return NULL;
- break;
- }
-
-
- /* Setup TQ3TriGridData */
- data.numRows = (unsigned long) ((vvMax - vvMin) / vvStep) + 1;
- data.numColumns = (unsigned long) ((uuMax - uuMin) / uuStep) + 1;
- data.facetAttributeSet = NULL;
- data.triGridAttributeSet= NULL;
-
- data.vertices = (TQ3Vertex3D *) NewPtrClear (data.numRows * data.numColumns * sizeof(TQ3Vertex3D));
- if (data.vertices == NULL)
- {
- ERROR_DEBUG_STR("Error: NewLibraryTriGrid ; Out of memory for triGrid vertices, geometry library number");
- return NULL;
- }
-
- /* Set trigrid vertices and shading UVs, if it hasUVAttributes */
- vertices = data.vertices;
- i = 0;
- for (vvValue = vvMin; vvValue <= vvMax; vvValue += vvStep)
- {
- for (uuValue = uuMin; uuValue <= uuMax; uuValue += uuStep)
- {
- switch (num)
- {
- /* Flat 5x5 */
- case kGeometryLibraryRange_Simple+0:
- case kGeometryLibraryRange_UVGeoAttributes+0:
- case kGeometryLibraryRange_UVFaceAttributes+0:
- vertices[i].point.x = uuValue;
- vertices[i].point.y = vvValue;
- vertices[i].point.z = 0;
- break;
-
- /* Splash */
- case kGeometryLibraryRange_Simple+3:
- case kGeometryLibraryRange_UVGeoAttributes+3:
- case kGeometryLibraryRange_UVFaceAttributes+3:
- vertices[i].point.x = uuValue;
- vertices[i].point.y = vvValue;
- vertices[i].point.z = 1.5 * uMath_Sin_Deg(48.0 * uuValue * vvValue) *
- uMath_Cos_Deg(48.0 * uuValue * vvValue);
- break;
-
- /* Steps */
- case kGeometryLibraryRange_Simple+7:
- case kGeometryLibraryRange_UVGeoAttributes+7:
- case kGeometryLibraryRange_UVFaceAttributes+7:
- vertices[i].point.x = uuValue;
- vertices[i].point.y = vvValue;
- vertices[i].point.z = kStepScale * (((long) uuValue) % ((data.numRows-1)/2)) *
- (((long) vvValue) % ((data.numColumns-1)/2));
- break;
- }
-
- if (hasUVAttributes)
- {
- if (mHasUVGeoAttributes(num))
- {
- param2D.u = (uuValue - uuMin) / (uuMax - uuMin);
- param2D.v = (vvValue - vvMin) / (vvMax - vvMin);
- }
- else /* mHasUVFaceAttributes */
- {
- param2D.u = i % data.numColumns;
- param2D.v = i / data.numColumns;
- }
-
- vertices[i].attributeSet = Q3AttributeSet_New();
- if (vertices[i].attributeSet != NULL)
- Q3AttributeSet_Add(vertices[i].attributeSet, kQ3AttributeTypeShadingUV, ¶m2D);
- }
- else
- vertices[i].attributeSet = NULL;
-
- i++;
- }
- }
-
- if (addNormals)
- AddVertexNormals(num, &data);
-
- geometryObject = Q3TriGrid_New (&data);
-
- if (hasUVAttributes)
- {
- for (i = 0; i < data.numRows * data.numColumns; i++)
- {
- if (vertices[i].attributeSet != NULL)
- Q3Object_Dispose(vertices[i].attributeSet);
- }
- }
- DisposePtr ((void *) vertices);
- }
- break;
-
- case kGeometryLibraryRange_Simple+1: /* Torus */
- case kGeometryLibraryRange_UVGeoAttributes+1:
- case kGeometryLibraryRange_UVFaceAttributes+1:
- case kGeometryLibraryRange_Simple+2: /* Wavey Torus */
- case kGeometryLibraryRange_UVGeoAttributes+2:
- case kGeometryLibraryRange_UVFaceAttributes+2:
- case kGeometryLibraryRange_Simple+4: /* Sphere */
- case kGeometryLibraryRange_UVGeoAttributes+4:
- case kGeometryLibraryRange_UVFaceAttributes+4:
- case kGeometryLibraryRange_Simple+5: /* Cone */
- case kGeometryLibraryRange_UVGeoAttributes+5:
- case kGeometryLibraryRange_UVFaceAttributes+5:
- case kGeometryLibraryRange_Simple+6: /* Pipe */
- case kGeometryLibraryRange_UVGeoAttributes+6:
- case kGeometryLibraryRange_UVFaceAttributes+6:
- case kGeometryLibraryRange_Simple+8: /* Spring */
- case kGeometryLibraryRange_UVGeoAttributes+8:
- case kGeometryLibraryRange_UVFaceAttributes+8:
- {
- /* Setup min, max and step values trigrid vertex u & v values */
- switch (num)
- {
- /**
- ** Torus
- **/
- case kGeometryLibraryRange_Simple+1:
- case kGeometryLibraryRange_UVGeoAttributes+1:
- case kGeometryLibraryRange_UVFaceAttributes+1:
- /**
- ** Wavey Torus
- **/
- case kGeometryLibraryRange_Simple+2:
- case kGeometryLibraryRange_UVGeoAttributes+2:
- case kGeometryLibraryRange_UVFaceAttributes+2:
-
- addNormals = kQ3True;
-
- /*
- * uuValue is used to generate each circular cross section about the y axis
- * vvValue is used to revolve the circular cross section about the torus' center
- */
- #define kTorusCrossRadius 0.5
- #define kTorusInnerRadius 1.0
- #define kTorusWaveyAmpRadius 5.0
-
- uuMin = 0.0;
- uuMax = 360.0;
- vvMin = -180.0;
- vvMax = 180.0;
- if (hasUVAttributes) {
- uuStep = 12.0; /* 10.0; */
- vvStep = 12.0; /* 10.0; */
- } else {
- uuStep = 10.0;
- vvStep = 10.0;
- }
- break;
-
- /**
- ** Sphere
- **/
- case kGeometryLibraryRange_Simple+4:
- case kGeometryLibraryRange_UVGeoAttributes+4:
- case kGeometryLibraryRange_UVFaceAttributes+4:
-
- addNormals = kQ3True;
-
- /*
- * uuValue is an angle used to revolve the cross section about the y axis
- * vvValue is an angle used to generate each half circular cross section
- */
- uuMin = 0.0;
- uuMax = 360.0;
- vvMin = - 90.0;
- vvMax = 90.0;
- if (hasUVAttributes) {
- uuStep = 12.0; /* 10.0; */
- vvStep = 12.0; /* 10.0; */
- } else {
- uuStep = 9.0;
- vvStep = 9.0;
- }
- radius = 1.0;
- break;
-
- /**
- ** Cone
- **/
- case kGeometryLibraryRange_Simple+5:
- case kGeometryLibraryRange_UVGeoAttributes+5:
- case kGeometryLibraryRange_UVFaceAttributes+5:
-
- addNormals = kQ3True;
-
- /*
- * vvValue is the length of the cone side from point to the edge
- * uuValue is an angle used to revolve the cross section about the y axis
- */
- if (hasUVAttributes) {
- uuStep = 24.0; /* 15.0; */
- vvStep = 0.25;
- } else {
- uuStep = 10.0;
- vvStep = 0.25;
- }
- uuMin = 0.0;
- uuMax = 360.0;
- vvMin = -vvStep;
- vvMax = 2.0;
-
- radius = 0.5;
- break;
-
- /**
- ** Pipe
- **/
- case kGeometryLibraryRange_Simple+6:
- case kGeometryLibraryRange_UVGeoAttributes+6:
- case kGeometryLibraryRange_UVFaceAttributes+6:
-
- addNormals = kQ3True;
-
- /*
- * uuValue is used to revolve the line cross section about the y axis
- * vvValue is used to generate the length of the pipe
- */
- if (hasUVAttributes) {
- uuStep = 20.0; /* 10.0; */
- vvStep = 0.5;
- } else {
- uuStep = 10.0; /* 15.0; */
- vvStep = 0.3;
- }
- uuMin = 0.0;
- uuMax = 360.0;
- vvMin = - 1.5;
- vvMax = 1.5;
- #ifdef FINISH_THIS
- vvMin = - 1.5 - vvStep;
- vvMax = 1.5 + vvStep;
- #else /* FINISH_THIS */
- vvMin = - 1.5;
- vvMax = 1.5;
- #endif /* FINISH_THIS */
- radius = 1.0;
- break;
-
- /**
- ** Spring
- **/
- case kGeometryLibraryRange_Simple+8:
- case kGeometryLibraryRange_UVGeoAttributes+8:
- case kGeometryLibraryRange_UVFaceAttributes+8:
-
- addNormals = kQ3True;
-
- /*
- * uuValue is used to revolve the circular cross section about the springs' axis
- * vvValue is used to generate each circular cross section
- */
- #define kSpringCrossRadius 0.25
- #define kSpringInnerRadius 1.0
- #define kSpringSpacing 3.5*kSpringCrossRadius
-
- uuMin = - 90.0;
- uuMax = 810.0;
- vvMin = -180.0;
- vvMax = 180.0;
- if (hasUVAttributes) {
- uuStep = 15.0; /* 30.0; */
- vvStep = 30.0;
- } else {
- uuStep = 15.0; /* 20.0; */
- vvStep = 15.0;
- }
- break;
-
- default:
- DebugStr("\pWarning: NewLibraryTriGrid ; unknown revolved trigrid index");
- return NULL;
- break;
- }
-
-
- /* Setup TQ3TriGridData */
- data.numRows = (unsigned long) ((vvMax - vvMin) / vvStep) + 1;
- data.numColumns = (unsigned long) ((uuMax - uuMin) / uuStep) + 1;
- data.facetAttributeSet = NULL;
- data.triGridAttributeSet= NULL;
-
- data.vertices = (TQ3Vertex3D *) NewPtrClear (data.numRows * data.numColumns * sizeof(TQ3Vertex3D));
- if (data.vertices == NULL)
- {
- ERROR_DEBUG_STR("Error: NewLibraryTriGrid ; Out of memory for triGrid vertices.");
- return NULL;
- }
-
- /* Set trigrid vertices and shading UVs, if it hasUVAttributes */
- vertices = data.vertices;
- i = 0;
- for (vvValue = vvMin; vvValue <= vvMax; vvValue += vvStep)
- {
- for (uuValue = uuMax; uuValue >= uuMin; uuValue -= uuStep)
- {
- switch (num)
- {
- /* Torus */
- case kGeometryLibraryRange_Simple+1:
- case kGeometryLibraryRange_UVGeoAttributes+1:
- case kGeometryLibraryRange_UVFaceAttributes+1:
- vertices[i].point.x = (uMath_Cos_Deg(vvValue) * kTorusCrossRadius + kTorusInnerRadius) * uMath_Cos_Deg(uuValue);
- vertices[i].point.y = uMath_Sin_Deg(vvValue) * kTorusCrossRadius;
- vertices[i].point.z = (uMath_Cos_Deg(vvValue) * kTorusCrossRadius + kTorusInnerRadius) * uMath_Sin_Deg(uuValue);
- break;
-
- /* Wavey Torus */
- case kGeometryLibraryRange_Simple+2:
- case kGeometryLibraryRange_UVGeoAttributes+2:
- case kGeometryLibraryRange_UVFaceAttributes+2:
- radius = kTorusCrossRadius / kTorusWaveyAmpRadius * uMath_Sin_Deg(kTorusWaveyAmpRadius * uuValue) + kTorusCrossRadius;
- vertices[i].point.x = (uMath_Cos_Deg(vvValue) * radius + kTorusInnerRadius) * uMath_Cos_Deg(uuValue);
- vertices[i].point.y = uMath_Sin_Deg(vvValue) * radius;
- vertices[i].point.z = (uMath_Cos_Deg(vvValue) * radius + kTorusInnerRadius) * uMath_Sin_Deg(uuValue);
- break;
-
- /* Sphere */
- case kGeometryLibraryRange_Simple+4:
- case kGeometryLibraryRange_UVGeoAttributes+4:
- case kGeometryLibraryRange_UVFaceAttributes+4:
- vertices[i].point.x = uMath_Cos_Deg(vvValue) * uMath_Cos_Deg(uuValue) * radius;
- vertices[i].point.y = uMath_Sin_Deg(vvValue) * radius;
- vertices[i].point.z = uMath_Cos_Deg(vvValue) * uMath_Sin_Deg(uuValue) * radius;
- break;
-
- /* Cone */
- case kGeometryLibraryRange_Simple+5:
- case kGeometryLibraryRange_UVGeoAttributes+5:
- case kGeometryLibraryRange_UVFaceAttributes+5:
- if (vvValue < (vvMin + vvStep))
- {
- vertices[i].point.x = 0.0;
- vertices[i].point.y = vvMin + vvStep;
- vertices[i].point.z = 0.0;
- }
- else
- {
- vertices[i].point.x = (vvMax - vvValue) * uMath_Cos_Deg(uuValue) * radius;
- vertices[i].point.y = vvValue;
- vertices[i].point.z = (vvMax - vvValue) * uMath_Sin_Deg(uuValue) * radius;
- }
- break;
-
- /* Pipe */
- case kGeometryLibraryRange_Simple+6:
- case kGeometryLibraryRange_UVGeoAttributes+6:
- case kGeometryLibraryRange_UVFaceAttributes+6:
- #ifdef FINISH_THIS
- if (vvValue < (vvMin + vvStep))
- {
- vertices[i].point.x = 0.0;
- vertices[i].point.y = vvMin + vvStep;
- vertices[i].point.z = 0.0;
- }
- else
- if (vvValue > (vvMax - vvStep))
- {
- vertices[i].point.x = 0.0;
- vertices[i].point.y = vvMax - vvStep;
- vertices[i].point.z = 0.0;
- }
- else
- {
- vertices[i].point.x = uMath_Cos_Deg(uuValue) * radius;
- vertices[i].point.y = vvValue;
- vertices[i].point.z = uMath_Sin_Deg(uuValue) * radius;
- }
- #else /* FINISH_THIS */
- vertices[i].point.x = radius * uMath_Cos_Deg(uuValue);
- vertices[i].point.y = vvValue;
- vertices[i].point.z = radius * uMath_Sin_Deg(uuValue);
- #endif /* FINISH_THIS */
- break;
-
- /* Spring */
- case kGeometryLibraryRange_Simple+8:
- case kGeometryLibraryRange_UVGeoAttributes+8:
- case kGeometryLibraryRange_UVFaceAttributes+8:
- vertices[i].point.x = (uMath_Cos_Deg(vvValue) * kSpringCrossRadius + kSpringInnerRadius) * uMath_Cos_Deg(uuValue);
- vertices[i].point.y = uMath_Sin_Deg(vvValue) * kSpringCrossRadius + kSpringSpacing * uuValue/360.0;
- vertices[i].point.z = (uMath_Cos_Deg(vvValue) * kSpringCrossRadius + kSpringInnerRadius) * uMath_Sin_Deg(uuValue);
- break;
- }
-
- if (hasUVAttributes)
- {
- if (mHasUVGeoAttributes(num))
- {
- param2D.u = 1.0 - ((uuValue - uuMin) / (uuMax - uuMin));
- param2D.v = (vvValue - vvMin) / (vvMax - vvMin);
- }
- else /* mHasUVFaceAttributes */
- {
- param2D.u = i % data.numColumns;
- param2D.v = i / data.numColumns;
- }
-
- vertices[i].attributeSet = Q3AttributeSet_New();
- if (vertices[i].attributeSet != NULL)
- Q3AttributeSet_Add(vertices[i].attributeSet, kQ3AttributeTypeShadingUV, ¶m2D);
- }
- else
- vertices[i].attributeSet = NULL;
-
- i++;
- }
- }
-
- if (addNormals)
- AddVertexNormals(num, &data);
-
- geometryObject = Q3TriGrid_New (&data);
-
- if (hasUVAttributes)
- {
- for (i = 0; i < data.numRows * data.numColumns; i++)
- {
- if (vertices[i].attributeSet != NULL)
- Q3Object_Dispose(vertices[i].attributeSet);
- }
- }
- DisposePtr ((void *) vertices);
- }
- break;
-
- default:
- DebugStr("\pWarning: NewLibraryTriGrid ; index unimplemented ");
- break;
- }
-
- return geometryObject;
- }
-
-
- void AddVertexNormals(
- unsigned long geoNum,
- TQ3TriGridData *pTriData)
- {
- TQ3Vector3D vector3D;
- TQ3Point3D point3D;
- TQ3Vertex3D *pVertices;
- unsigned long i,
- j,
- k;
-
- pVertices = pTriData->vertices;
-
- if (
- /* Torus */
- geoNum == kGeometryLibraryRange_Simple+1 ||
- geoNum == kGeometryLibraryRange_UVGeoAttributes+1 ||
- geoNum == kGeometryLibraryRange_UVFaceAttributes+1 ||
- /* Wavey Torus */
- geoNum == kGeometryLibraryRange_Simple+2 ||
- geoNum == kGeometryLibraryRange_UVGeoAttributes+2 ||
- geoNum == kGeometryLibraryRange_UVFaceAttributes+2 ||
- /* Spring */
- geoNum == kGeometryLibraryRange_Simple+8 ||
- geoNum == kGeometryLibraryRange_UVGeoAttributes+8 ||
- geoNum == kGeometryLibraryRange_UVFaceAttributes+8
- )
- {
- unsigned long i2;
-
- i2 = pTriData->numColumns * (pTriData->numRows/2);
-
- #define p1 pVertices[i].point
- #define p2 pVertices[i2].point
-
- i = 0;
- for (k = 0; k < pTriData->numRows / 2; k++)
- {
- for (j = 0; j < pTriData->numColumns; j++)
- {
- /* Create an attribute set for non-textured geometry */
- if (pVertices[i ].attributeSet == NULL)
- pVertices[i ].attributeSet = Q3AttributeSet_New();
- if (pVertices[i2].attributeSet == NULL)
- pVertices[i2].attributeSet = Q3AttributeSet_New();
-
- switch (geoNum)
- {
- /* Torus */
- case kGeometryLibraryRange_Simple+1:
- case kGeometryLibraryRange_UVGeoAttributes+1:
- case kGeometryLibraryRange_UVFaceAttributes+1:
- /* Wavey Torus */
- case kGeometryLibraryRange_Simple+2:
- case kGeometryLibraryRange_UVGeoAttributes+2:
- case kGeometryLibraryRange_UVFaceAttributes+2:
- /* Spring */
- case kGeometryLibraryRange_Simple+8:
- case kGeometryLibraryRange_UVGeoAttributes+8:
- case kGeometryLibraryRange_UVFaceAttributes+8:
- /* point3D is midpoint */
- Q3Point3D_Set (&point3D,
- (uMath_Fabs(p2.x - p1.x) / 2) + uMath_Min(p1.x, p2.x),
- (uMath_Fabs(p2.y - p1.y) / 2) + uMath_Min(p1.y, p2.y),
- (uMath_Fabs(p2.z - p1.z) / 2) + uMath_Min(p1.z, p2.z)
- );
- Q3Point3D_Subtract(&pVertices[i].point, &point3D, &vector3D);
- break;
- }
-
- if ((i % pTriData->numColumns) != (pTriData->numRows / 2))
- {
- Q3Vector3D_Normalize(&vector3D, &vector3D);
- Q3AttributeSet_Add(pVertices[i].attributeSet, kQ3AttributeTypeNormal, &vector3D);
- }
-
- Q3Vector3D_Negate(&vector3D, &vector3D);
- Q3Vector3D_Normalize(&vector3D, &vector3D);
- Q3AttributeSet_Add(pVertices[i2].attributeSet, kQ3AttributeTypeNormal, &vector3D);
- i++;
- i2++;
- }
- }
-
- #undef p1
- #undef p2
-
- return;
- }
- else
- if (
- /* Splash */
- geoNum == kGeometryLibraryRange_Simple+3 ||
- geoNum == kGeometryLibraryRange_UVGeoAttributes+3 ||
- geoNum == kGeometryLibraryRange_UVFaceAttributes+3
- )
- {
- TQ3Point3D point3Dc,
- point3Dr;
-
- /* C = numColumns
- * i = vertex index
- *
- * i+C
- *
- * i-1 i i+1
- *
- * i-C
- */
- #define pL pVertices[i-1].point
- #define pR pVertices[i+1].point
- #define pT pVertices[i+pTriData->numColumns].point
- #define pB pVertices[i-pTriData->numColumns].point
- #define pH point3Dc
- #define pV point3Dr
-
- i = pTriData->numColumns + 1;
- for (k = 1;
- k <= pTriData->numRows - 2;
- k++)
- {
- for (j = 1;
- j <= pTriData->numColumns - 2;
- j++)
- {
- /* Create an attribute set for non-textured geometry */
- if (pVertices[i].attributeSet == NULL)
- pVertices[i].attributeSet = Q3AttributeSet_New();
-
- /* point3Dc, point3Dr, point3D are midpoints */
-
- /* i-1 and i+1 */
- Q3Point3D_Set (&point3Dc,
- (uMath_Fabs(pR.x - pL.x) / 2) + uMath_Min(pL.x, pR.x),
- (uMath_Fabs(pR.y - pL.y) / 2) + uMath_Min(pL.y, pR.y),
- (uMath_Fabs(pR.z - pL.z) / 2) + uMath_Min(pL.z, pR.z)
- );
-
- /* i-C and i+C */
- Q3Point3D_Set (&point3Dr,
- (uMath_Fabs(pT.x - pB.x) / 2) + uMath_Min(pB.x, pT.x),
- (uMath_Fabs(pT.y - pB.y) / 2) + uMath_Min(pB.y, pT.y),
- (uMath_Fabs(pT.z - pB.z) / 2) + uMath_Min(pB.z, pT.z)
- );
-
- /* point3Dc and point3Dr */
- Q3Point3D_Set (&point3D,
- (uMath_Fabs(pH.x - pV.x) / 2) + uMath_Min(pV.x, pH.x),
- (uMath_Fabs(pH.y - pV.y) / 2) + uMath_Min(pV.y, pH.y),
- (uMath_Fabs(pH.z - pV.z) / 2) + uMath_Min(pV.z, pH.z)
- );
-
- Q3Point3D_Subtract(&pVertices[i].point, &point3D, &vector3D);
- Q3Vector3D_Normalize(&vector3D, &vector3D);
- Q3AttributeSet_Add(pVertices[i].attributeSet, kQ3AttributeTypeNormal, &vector3D);
-
- i += ((i+2) % pTriData->numColumns == 0) ? 3 : 1;
- }
- }
-
- #undef pL
- #undef pR
- #undef pT
- #undef pB
- #undef pH
- #undef pV
-
- return;
- }
-
-
- /*
- * Sphere
- * Cone
- * Pipe
- */
- i = 0;
- for (k = 0; k < pTriData->numRows; k++)
- {
- for (j = 0; j < pTriData->numColumns; j++)
- {
- /* Create an attribute set for non-textured geometry */
- if (pVertices[i].attributeSet == NULL)
- pVertices[i].attributeSet = Q3AttributeSet_New();
-
- switch (geoNum)
- {
- /* Sphere */
- case kGeometryLibraryRange_Simple+4:
- case kGeometryLibraryRange_UVGeoAttributes+4:
- case kGeometryLibraryRange_UVFaceAttributes+4:
- Q3Point3D_Set (&point3D, 0.0, 0.0, 0.0);
- Q3Point3D_Subtract(&pVertices[i].point, &point3D, &vector3D);
- break;
-
- /* Cone */
- case kGeometryLibraryRange_Simple+5:
- case kGeometryLibraryRange_UVGeoAttributes+5:
- case kGeometryLibraryRange_UVFaceAttributes+5:
- Q3Point3D_Set ( &point3D,
- 0.0,
- /**/ ((pVertices[i].point.y > kQ3RealZero) ||
- (pVertices[i].point.y == kQ3RealZero &&
- Q3Vector3D_Length((TQ3Vector3D *) &pVertices[i].point) == 0.5))
- ? pVertices[i].point.y
- : 100.0,
- 0.0);
- Q3Point3D_Subtract(&pVertices[i].point, &point3D, &vector3D);
- break;
-
- /* Pipe */
- case kGeometryLibraryRange_Simple+6:
- case kGeometryLibraryRange_UVGeoAttributes+6:
- case kGeometryLibraryRange_UVFaceAttributes+6:
- Q3Point3D_Set (&point3D, 0.0, pVertices[i].point.y, 0.0);
- Q3Point3D_Subtract(&pVertices[i].point, &point3D, &vector3D);
- break;
- }
-
- Q3Vector3D_Normalize(&vector3D, &vector3D);
- Q3AttributeSet_Add(pVertices[i].attributeSet, kQ3AttributeTypeNormal, &vector3D);
- i++;
- } /* for j */
- } /* for k */
- }
-